//
// Created by jiaxv on 2025/8/11.
//

#ifndef LDACS_CORENET_GROUND_H
#define LDACS_CORENET_GROUND_H
#include "define.h"
#include "ldacs_corenet.h"
#include "util/log.h"

#define G1_TYP_LEN 8
#define G1_G3_G5_PKT_HEAD_LEN 4
#define G1_G3_AS_INI_HEAD_LEN 9

typedef enum {
    G1_SAC_RQST = 0x96,
    G1_SAC_RESP = 0x67,
    G1_INIT_AS = 0xD1,
    G1_SNF_UPLOAD = 0x72,
    G1_SNF_DOWNLOAD = 0xD3,
    G1_KEY_TRANS = 0x75,
    G1_DATA_BEARER_EST_RQST = 0x6C,
    G1_DATA_BEARER_EST_RESP = 0x9D,
    G1_AS_EXIT = 0x98,
    G1_RELEASE_AS_CONTEXT = 0x69,
    G1_HANDOVER_REQUEST = 0X51,
    G1_KEY_UPDATE_REMIND = 0XDF,
    G1_PATH_SWITCH_REQUEST = 0X9A,
    G1_PATH_SWITCH_RESPONSE = 0X6B,
    G1_HANDOVER_REQUEST_ACK = 0X52,
    G1_AS_STATE_CHANGE = 0xEE,
} G1_TYPE;

typedef enum {
    G1U_DATA_DOWNLOAD = 14,
} G1U_TYPE;

typedef enum {
    G3_INIT_AS = 0xD1,
    G3_SNF_UPLOAD = 0x72,
    G3_SNF_DOWNLOAD = 0xD3,
    G3_AS_AUZ_INFO = 0xB4,
    G3_KEY_TRANS = 0x75,
    G3_AS_STATE_CHANGE = 0xEE,
    G3_KEY_UPDATE_REMIND = 0XDF,
} G3_TYPE;

typedef enum {
    G5_AS_AUZ_INFO = 0xB4,
    G5_DATA_BEARER_EST_RQST = 0x6C,
    G5_DATA_BEARER_EST_RESP = 0x9D,
    G5_AS_STATE_CHANGE = 0xEE,
    G5_AS_EXIT = 0x98,
    G5_PATH_SWITCH_REQUEST = 0X9A,
    G5_PATH_SWITCH_RESPONSE = 0X6B,
} G5_TYPE;

typedef enum {
    G7_DATA_BEARER_SESSION_COMMAND = 0xA1,
    G7_DATA_BEARER_SESSION_COMPLETE = 0xA2,
} G7_TYPE;

#pragma pack(1)
typedef struct g1_sac_rqst_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint32_t AS_UA;
}g1_sac_rqst_t;
extern struct_desc_t g1_sac_rqst_desc;

typedef struct g1_sac_resp_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint32_t AS_UA;
}g1_sac_resp_t;
extern struct_desc_t g1_sac_resp_desc;

typedef struct g1_g3_init_as_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint32_t AS_UA;
    uint16_t GS_SAC;
    uint8_t element_type;
    buffer_t *sdu;
}g1_g3_init_as_t;
extern struct_desc_t g1_g3_init_as_desc;

static void free_g1_g3_init_as(void *args) {
    g1_g3_init_as_t *init = args;
    if (init) {
        if (init->sdu) {
            free_buffer(init->sdu);
        }
        free(init);
    }
}

typedef struct g1_g3_snf_pkt_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint8_t element_type;
    buffer_t *sdu;
}g1_g3_snf_pkt_t;
extern struct_desc_t g1_g3_snf_pkt_desc;

static void free_g1_g3_snf_pkt(void *args) {
    g1_g3_snf_pkt_t *upload = args;
    if (upload) {
        if (upload->sdu) {
            free_buffer(upload->sdu);
        }
        free(upload);
    }
}


typedef struct g3_g5_as_auz_info_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint8_t is_legal;
    uint8_t auz_type;
}g3_g5_as_auz_info_t;
extern struct_desc_t g3_g5_as_auz_info_desc;

typedef struct g1_g5_bearer_est_rqst_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint8_t element_type;
    buffer_t *snf_msg;
    buffer_t *IP;
    uint16_t port;
}g1_g5_bearer_est_t;
extern struct_desc_t g1_g5_bearer_est_desc;

typedef struct g1_g5_as_release_exit_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
}g1_g5_as_release_exit_t;
extern struct_desc_t g1_g5_as_release_exit_desc;


static void free_g1_g5_bearer_est(void *args) {
    g1_g5_bearer_est_t *bearer = args;
    if (bearer) {
        if (bearer->snf_msg) {
            free_buffer(bearer->snf_msg);
        }
        if (bearer->IP) {
            free_buffer(bearer->IP);
        }
        free(bearer);
    }
}

typedef struct g7_bearer_command_type1_s {
    buffer_t *IP_AS;
    buffer_t *IP_GS;
    uint16_t port_gs;
}g7_bearer_command_type1_t;
extern struct_desc_t g7_bearer_command_type1_desc;

static void free_g7_bearer_type1_command(void *args) {
    g7_bearer_command_type1_t *bearer = args;
    if (bearer) {
        if (bearer->IP_AS) {
            free_buffer(bearer->IP_AS);
        }
        if (bearer->IP_GS) {
            free_buffer(bearer->IP_GS);
        }
        free(bearer);
    }
}

typedef struct g7_bearer_command_type2_s {
    buffer_t *IP_GS;
    uint16_t port_gs;
}g7_bearer_command_type2_t;
extern struct_desc_t g7_bearer_command_type2_desc;

static void free_g7_bearer_type2_command(void *args) {
    g7_bearer_command_type2_t *bearer = args;
    if (bearer) {
        if (bearer->IP_GS) {
            free_buffer(bearer->IP_GS);
        }
        free(bearer);
    }
}


#define G7_BEARER_HEADER_LEN 4

typedef enum {
    ACCESS = 0x1,
    SWITCH = 0x2,
    EXIT = 0x3,
}G7_CMD_TYPE;

typedef struct g7_bearer_command_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint8_t CMD_TYPE;
    uint8_t SERVICE;
    buffer_t *sdu;
}g7_bearer_command_t;
extern struct_desc_t g7_bearer_command_desc;

static void free_g7_bearer_command(void *args) {
    g7_bearer_command_t *bearer = args;
    if (bearer) {
        if (bearer->sdu) {
            free_buffer(bearer->sdu);
        }
        free(bearer);
    }
}

typedef struct g7_bearer_complete_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint8_t CMD_TYPE;
}g7_bearer_complete_t;
extern struct_desc_t g7_bearer_complete_desc;


typedef struct g1_g3_g5_as_st_chg_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint8_t STATE;
    uint16_t GS_SAC;
}g1_g3_g5_as_st_chg_t;
extern struct_desc_t g1_g3_g5_as_st_chg_desc;

typedef struct g1_handover_request_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint32_t AS_UA; //////////////////////////////// 为统一GSG的处理 添加
    uint16_t GSS_SAC;
    uint16_t GST_SAC;
}g1_ho_rqst_t;
extern struct_desc_t g1_handover_request_desc;

typedef struct g1_g3_key_update_remind_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint8_t element_type;
    uint16_t GSS_SAC;
    uint16_t GST_SAC;
}g1_g3_key_update_remind_t;
extern struct_desc_t g1_g3_key_update_remind_desc;

typedef struct g1_g5_path_switch_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    buffer_t *IP;
    uint16_t port;
}g1_g5_path_switch_t;
extern struct_desc_t g1_g5_path_switch_desc;

static void free_g1_g5_path_switch(void *args) {
    g1_g5_path_switch_t *bearer = args;
    if (bearer) {
        if (bearer->IP) {
            free_buffer(bearer->IP);
        }
        free(bearer);
    }
}

typedef struct g1_ho_rqst_ack_s {
    uint8_t GTYPE;
    uint8_t VERSION;
    uint16_t AS_SAC;
    uint16_t NEXT_CO;
}g1_ho_rqst_ack_t;
extern struct_desc_t g1_ho_rqst_ack_desc;

#pragma pack()

extern size_t g1_format_size ;
extern cn_format_desc_t g1_format_descs[];
extern size_t g3_format_size ;
extern cn_format_desc_t g3_format_descs[];
extern size_t g5_format_size ;
extern cn_format_desc_t g5_format_descs[];
extern size_t g7_format_size ;
extern cn_format_desc_t g7_format_descs[];

l_err g1u_2_gau(net_element_t *net_ele, buffer_t *in_buf, element_propt_t *propt);

l_err gau_2_g1u(net_element_t *net_ele, buffer_t *in_buf, element_propt_t *propt);

#endif //LDACS_CORENET_GROUND_H